#include "stdafx.h"
#include "Timer.h"

#include "Exception.h"

namespace Cvekas {

int64 Timer::perf_frequency;
int64 Timer::start_time;
int64 Timer::current_time;

int Timer::old_time_ms;
int Timer::current_time_ms;
int Timer::d_time_ms;
float Timer::time_scale;

int Timer::last_fps_update;
int Timer::frames_drawn;
int Timer::fps;

int64 TimeStamp::frequency;

void Timer::reset()
{
	current_time_ms = 0;

	QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency);
	if(perf_frequency == 0)
		throw EXCEPTION("Unable to reset Timer");
	TimeStamp::frequency = perf_frequency;

	QueryPerformanceCounter((LARGE_INTEGER*)&start_time);
	update();
}

void Timer::update()
{
	old_time_ms = current_time_ms;
	QueryPerformanceCounter((LARGE_INTEGER*)&current_time);
	current_time_ms = perfCounterToMs(current_time);
	d_time_ms = current_time_ms - old_time_ms;
	time_scale = (float)d_time_ms / 1000.0f;
	if (last_fps_update + 1000 <= current_time_ms)
	{
		fps = frames_drawn;
		frames_drawn = 0;
		last_fps_update = current_time_ms;
	}
	frames_drawn++;
}

int Timer::getFPS()
{
	return fps;
}

float Timer::getTimeScale()
{
	return time_scale;
}

int Timer::getDTimeMs()
{
	return d_time_ms;
}

int Timer::getTimeMs()
{
	return current_time_ms;
}

TimeStamp Timer::getTimeStamp()
{
	TimeStamp result;
	QueryPerformanceCounter((LARGE_INTEGER*)&result.value);
	return result;
}

std::string Timer::msToString(int time)
{
	int s = time / 1000;
	int min = s / 60;
	int sec = s % 60;
	return FORMAT("%02d:%02d", % min % sec);
}

int Timer::perfCounterToMs(long long time)
{
	return (int)((time - start_time) * 1000 / perf_frequency);
}

} // namespace
